home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / umich / network / ka9q / ka9q_src.arc / AXMBX.C < prev    next >
C/C++ Source or Header  |  1988-07-28  |  7KB  |  325 lines

  1. /* cat > ./ax_mbx.c << '\Rogue\Monster\' */
  2. #include <stdio.h>
  3. #include <time.h>
  4. #include <ctype.h>
  5. #include "global.h"
  6. #include "mbuf.h"
  7. #include "ax25.h"
  8. #include "timer.h"
  9. #include "iface.h"
  10. #include "lapb.h"
  11. #include "ax_mbx.h"
  12. #include "cmdparse.h"
  13.  
  14. static char mbbanner[] = "Welcome to the %s TCP/IP Mailbox\r" ;
  15. static char mbmenu[] = "(C)hat, (S)end, (B)ye > " ;
  16.  
  17. void
  18. mbx_incom(axp,cnt)
  19. register struct ax25_cb *axp ;
  20. int16 cnt ;
  21. {
  22.     struct mbx *m ;
  23.     struct mbuf *bp, *recv_ax25() ;
  24.     char *cp ;
  25.     extern char hostname[] ;
  26.     void mbx_rx(), mbx_state() ;
  27.     extern char *index() ;
  28.     
  29.     if ((m = (struct mbx *)calloc(1,sizeof(struct mbx))) == NULLMBX) {
  30.         disc_ax25(axp) ;    /* no memory! */
  31.         return ;
  32.     }
  33.  
  34.     m->state = MBX_CMD ;    /* start in command state */
  35.     m->ax25_cb = axp ;
  36.  
  37.     pax25(m->name,&axp->addr.dest) ;
  38.     cp = index(m->name,'-') ;
  39.     if (cp != NULLCHAR)            /* get rid of SSID */
  40.         *cp = '\0' ;
  41.  
  42.     m->lp = m->line ;        /* point line pointer at buffer */
  43.     axp->r_upcall = mbx_rx ;
  44.     axp->s_upcall = mbx_state ;
  45.     axp->user = (char *)m ;
  46.  
  47.     /* The following is necessary because we didn't know we had a */
  48.     /* "real" ax25 connection until a data packet came in.  We    */
  49.     /* can't be spitting banners out at every station who connects, */
  50.     /* since they might be a net/rom or IP station.  Sorry.  */
  51.     
  52.     bp = recv_ax25(axp,cnt) ;        /* get the initial input */
  53.     free_p(bp) ;                /* and throw it away to avoid confusion */
  54.  
  55.     /* Now say hi */
  56.     
  57.     if ((bp = alloc_mbuf(strlen(hostname) + strlen(mbbanner) + 2)) == NULLBUF) {
  58.         disc_ax25(axp) ; /* mbx_state will fix stuff up */
  59.         return ;
  60.     }
  61.  
  62.     *bp->data = PID_FIRST | PID_LAST | PID_NO_L3 ;    /* pid */
  63.     bp->cnt = sprintf(bp->data+1,mbbanner,hostname) + 1 ;
  64.  
  65.     send_ax25(axp,bp) ;            /* send greeting message */
  66.     (void)mbx_msg(axp, mbmenu) ;        /* send initial menu prompt */    
  67. }
  68.  
  69. /* mbx_rx collects lines, and calls mbx_line when they are complete. */
  70. /* If the lines get too long, it arbitrarily breaks them. */
  71.  
  72. void mbx_rx(axp,cnt)
  73. struct ax25_cb *axp ;
  74. int16 cnt ;
  75. {
  76.     struct mbuf *bp, *recv_ax25() ;
  77.     struct mbx *m ;
  78.     char c ;
  79.     int mbx_line() ;
  80.     
  81.     m = (struct mbx *)axp->user ;
  82.     
  83.     if ((bp = recv_ax25(axp,cnt)) == NULLBUF)
  84.         return ;
  85.  
  86.     while (pullup(&bp,&c,1) == 1) {
  87.         if (c == '\r') {
  88.             *m->lp = '\0' ;            /* null terminate */
  89.             if (mbx_line(m) == -1) {    /* call the line processor */
  90.                 free_p(bp) ;        /* toss the rest */
  91.                 break ;                /* get out - we're obsolete */
  92.             }
  93.             m->lp = m->line ;        /* reset the pointer */
  94.         }
  95.         else if ((m->lp - m->line) == (MBXLINE - 1)) {
  96.             *m->lp++ = c ;
  97.             *m->lp = '\0' ;
  98.             if (mbx_line(m) == -1) {
  99.                 free_p(bp) ;
  100.                 break ;
  101.             }
  102.             m->lp = m->line ;
  103.         }
  104.         else
  105.             *m->lp++ = c ;
  106.     }
  107. }
  108.  
  109. void mbx_state(axp,old,new)
  110. struct ax25_cb *axp ;
  111. int old, new ;
  112. {
  113.     struct mbx *m ;
  114.     void free_mbx() ;
  115.     
  116.     m = (struct mbx *)axp->user ;
  117.  
  118.     /* dummy for now ... */
  119.     if (new == DISCONNECTED) {
  120.         axp->user = NULLCHAR ;
  121.         free_mbx(m) ;
  122.     }
  123. }
  124.  
  125. static void
  126. free_mbx(m)
  127. struct mbx *m ;
  128. {
  129.     if (m->to != NULLCHAR)
  130.         free(m->to) ;
  131.  
  132.     if (m->tfile != NULLFILE)
  133.         fclose(m->tfile) ;
  134.         
  135.     free(m) ;
  136. }
  137.  
  138.  
  139. static 
  140. mbx_line(m)
  141. struct mbx *m ;
  142. {
  143.     void ax_session() ;
  144.     char *host ;
  145.     extern char hostname[] ;
  146.     char fullfrom[80] ;
  147.     
  148.     if (m->state == MBX_CMD) {
  149.         switch (tolower(m->line[0])) {
  150.             case 'b':    /* bye - bye */
  151.                 disc_ax25(m->ax25_cb) ;
  152.                 return -1 ;    /* tell line processor to quit */
  153.                 break ;
  154.             case 'c':    /* chat */
  155.                 m->ax25_cb->user = NULLCHAR ;
  156.                 ax_session(m->ax25_cb,0) ;    /* make it a chat session */
  157.                 free_mbx(m) ;
  158.                 return -1 ;
  159.                 break ;
  160.             case 's':
  161.                 if (mbx_to(m) == -1) {
  162.                     mbx_msg(m->ax25_cb,
  163.                             "Bad address - try 'S name' or 'S name@host'\r") ;
  164.                     mbx_msg(m->ax25_cb,mbmenu) ;
  165.                 }
  166.                 else {
  167.                     m->state = MBX_SUBJ ;
  168.                     mbx_msg(m->ax25_cb,"Subject: ") ;
  169.                 }
  170.                 break ;
  171.             default:
  172.                 mbx_msg(m->ax25_cb,"Huh?\r") ;
  173.                 mbx_msg(m->ax25_cb,mbmenu) ;
  174.         }
  175.     return 0 ;
  176.     }
  177.     else if (m->state == MBX_SUBJ) {
  178.         if (mbx_data(m) == -1) {
  179.             mbx_msg(m->ax25_cb,"Can't create temp file for mail\r") ;
  180.             mbx_msg(m->ax25_cb,mbmenu) ;
  181.             free(m->to) ;
  182.             m->to = NULLCHAR ;
  183.             m->state = MBX_CMD ;
  184.             return 0 ;
  185.         }
  186.         m->state = MBX_DATA ;
  187.         mbx_msg(m->ax25_cb,
  188.             "Enter message.  Terminate with '.' alone in first column:\r") ;
  189.         return 0 ;
  190.     }
  191.     else if (m->state == MBX_DATA) {
  192.         if (m->line[0] == '.' && m->line[1] == '\0') {
  193.             if ((host = index(m->to,'@')) == NULLCHAR)
  194.                 host = hostname ;        /* use our hostname */
  195.             else
  196.                 host++ ;                /* use the host part of address */
  197.  
  198.             /* make up full from name for work file */
  199.             sprintf(fullfrom,"%s@%s",m->name,hostname) ;
  200.             
  201.             fseek(m->tfile,0L,0) ;        /* reset to beginning */
  202.             if (queuejob((void *)0,m->tfile,host,m->to,fullfrom) != 0)
  203.                 mbx_msg(m->ax25_cb,
  204.                         "Couldn't queue message for delivery\r") ;
  205.  
  206.             free(m->to) ;
  207.             m->to = NULLCHAR ;
  208.             fclose(m->tfile) ;
  209.             m->tfile = NULLFILE ;
  210.             m->state = MBX_CMD ;
  211.             mbx_msg(m->ax25_cb, mbmenu) ;
  212.             return 0 ;
  213.         }
  214.         /* not done yet! */
  215.         fprintf(m->tfile,"%s\n",m->line) ;
  216.         return 0 ;
  217.     }
  218. }
  219.  
  220. /* send text msg to ax.25 session axp */
  221. static
  222. mbx_msg(axp,msg)
  223. struct ax25_cb *axp ;
  224. char msg[] ;
  225. {
  226.     int len ;
  227.     struct mbuf *bp ;
  228.  
  229.     len = strlen(msg) ;
  230.  
  231.     if ((bp = alloc_mbuf(len+1)) == NULLBUF) {
  232.         disc_ax25(axp) ;
  233.         return -1 ;
  234.     }
  235.  
  236.     bp->cnt = len + 1 ;
  237.     
  238.     *bp->data = PID_FIRST | PID_LAST | PID_NO_L3 ;
  239.     
  240.     memcpy(bp->data+1, msg, len) ;
  241.  
  242.     send_ax25(axp,bp) ;
  243.  
  244.     return 0 ;
  245. }
  246.  
  247. /* Prepare the addressee.  If the address is bad, return -1, otherwise
  248.  * return 0
  249.  */
  250. static
  251. mbx_to(m)
  252. struct mbx *m ;
  253. {
  254.     register char *cp, *cp1 ;
  255.  
  256.     cp = m->line ;
  257.     while (!isspace(*cp))        /* skip the Send command */
  258.         if (*cp == '\0')        /* also stop for NULLs */
  259.             break ;
  260.         else
  261.             cp++ ;                /* try next character ... */
  262.  
  263.     if (*cp == '\0')            /* no address here */
  264.         return -1 ;
  265.  
  266.     while (isspace(*cp))        /* now skip the white space */
  267.         if (*cp == '\0')
  268.             break ;
  269.         else
  270.             cp++ ;
  271.  
  272.     if (*cp == '\0')            /* no address here */
  273.         return -1 ;
  274.  
  275.     cp1 = cp ;
  276.     while (!isspace(*cp1))        /* now find end of arg */
  277.         if (*cp1 == '\0')
  278.             break ;
  279.         else
  280.             cp1++ ;
  281.  
  282.     *cp1 = '\0' ;                /* null terminate the arg */
  283.  
  284. /*    if (checkaddress(cp) == 0) */    /* see how this address looks */
  285. /*        return -1 ;    */            /* oops */
  286.  
  287.     if ((m->to = malloc(strlen(cp) + 1)) == NULLCHAR)
  288.         return -1 ;                /* no room for address */
  289.  
  290.     strcpy(m->to,cp) ;            /* copy address */
  291.  
  292.     return 0 ;
  293. }
  294.  
  295. /* This opens the data file and writes the mail header into it.
  296.  * Returns 0 if OK, and -1 if not.
  297.  */
  298.  
  299. static
  300. mbx_data(m)
  301. struct mbx *m ;
  302. {
  303.     long t, time();        /* DG2KK: was: time_t */
  304.     char *ptime() ;
  305.     extern char hostname[] ;
  306.     extern FILE *tmpfile();
  307.     extern long get_msgid() ;
  308.     
  309.     if ((m->tfile = tmpfile()) == NULLFILE)
  310.         return -1 ;
  311.  
  312.     time(&t) ;
  313.     fprintf(m->tfile,"Date: %s",ptime(&t)) ;
  314.     fprintf(m->tfile,"Message-Id: <%ld@%s>\n",get_msgid(),hostname) ;
  315.     fprintf(m->tfile,"From: %s@%s\n",m->name,hostname) ;
  316.     fprintf(m->tfile,"To: %s\n",m->to) ;
  317.     fprintf(m->tfile,"Subject: %s\n\n",m->line) ;
  318.  
  319.     return 0 ;
  320. }
  321.  
  322. queuejob()
  323. {
  324. }
  325.